package web.common.internal.core.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import web.common.core.annotation.Facade;
import web.common.core.annotation.Provider;
import web.common.internal.core.validation.ValidationInvocationHandler;

import java.lang.reflect.Proxy;

/**
 * @author Jin Zheng
 * @since 1.0 2022-01-17
 */
public class ValidationBeanPostProcessor implements BeanPostProcessor {
	private static Logger logger = LoggerFactory.getLogger(ValidationBeanPostProcessor.class);

	public ValidationBeanPostProcessor() {
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		Class<?> clazz = AopUtils.getTargetClass(bean);
		if (!clazz.isAnnotationPresent(Provider.class)) {
			return bean;
		}
		var interfaces = clazz.getInterfaces();
		if (interfaces.length == 0) {
			return bean;
		}
		boolean found = false;
		for (var inter : interfaces) {
			if (inter.isAnnotationPresent(Facade.class)) {
				found = true;
				break;
			}
		}
		if (!found) {
			return bean;
		}

		var handler = new ValidationInvocationHandler(bean);
		ClassLoader loader = clazz.getClassLoader();
		var proxy = Proxy.newProxyInstance(loader, interfaces, handler);
		logger.info("Create proxy to validate parameter: {}", clazz.getName());
		return proxy;
	}

}
